<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Haapy Sheep and Grey Wolf</title>
<style type="text/css">
.grey-wolf {
	background-color: grey;
	position: absolute;
	width: 100px;
	height: 100px;
	border-radius: 50%;
	border: solid 2px darkgray;
	vertical-align: middle;
	text-align: center;
	z-index: 1;
}

.grey-wolf:after {
	content: 'Grey Wolf!';
	margin: auto;
	font-weight: bold;
	vertical-align: middle;
}

.beauty-sheep {
	background-color: white;
	position: absolute;
	width: 80px;
	height: 80px;
	border-radius: 40%;
	border: solid 6px pink;
	vertical-align: middle;
	text-align: center;
	z-index: 1;
}

.beauty-sheep:after {
	content: '(*^.^*)';
	font-family: Arial;
	margin: auto;
	font-weight: bold;
	vertical-align: middle;
}

.happy-sheep {
	background-color: #eee;
	position: absolute;
	width: 70px;
	height: 70px;
	border-radius: 30%;
	border: solid 10px black;
	vertical-align: middle;
	text-align: center;
	transform: rotate(90deg);
	z-index: 1;
}

.happy-sheep:after {
	content: ': )';
	font-family: Arial;
	margin: auto;
	font-weight: bold;
	vertical-align: middle;
}

.pot {
	background-color: red;
	position: absolute;
	width: 110px;
	height: 110px;
	border-radius: 100%;
	border: solid 2px black;
	text-align: center;
	z-index: 0;
}


.pot:after {
	content: 'Hot Pot';
	font-family: Arial;
	font-weight: bold;
	vertical-align: middle;
	color: white;
}

.grey-wolf:before, .beauty-sheep:before, .happy-sheep:before, .pot:before {
	content: '';
	display: inline-block;
	height: 100%;
	vertical-align: middle;
}

</style>
<script type="text/javascript">
;(function(exports) {

/* =========================================================================
   A naive MVC 
   ========================================================================= */

var naiveMVC = {};

/**
  * Model
  */

var GreenPlainModel = function (width, height) {
	this.width = width;
	this.height = height;

	return this;
};

var UIAnimate = function (x, y) {
	this.x = x; 
	this.y = y;
};

var GreyWolf = function (x, y) { UIAnimate.call(this, x, y);

	if(typeof GreyWolf.__initialized__ === 'undefined') {

		GreyWolf.prototype.laugh = function (message) {
			console.log('Ha haa haaaaaa!');
			alert(message);
		};

		GreyWolf.prototype.putToPot = function(sheep, pot) {
			console.log('Put you to pot, haha.');
			sheep.x = parseInt(pot.x) + 8 + 'px';
			sheep.y = parseInt(pot.y) + 8 + 'px';
		};


		GreyWolf.__initialized__ = true;
	}

	return this;
}; GreyWolf.prototype = new UIAnimate();

var BeautySheep = function (x, y, lover) { UIAnimate.call(this, x, y);
	this.lover = lover;
	lover.lover = this;

	if(typeof BeautySheep.__initialized__ === 'undefined') {

		BeautySheep.prototype.call = function (message) {
			console.log('Help please!!!');			
			alert(message);
			lover.help();
		};

		BeautySheep.__initialized__ = true;
	}

	return this;
}; BeautySheep.prototype = new UIAnimate();

var HappySheep = function(x, y) { UIAnimate.call(this, x, y);

	if(typeof HappySheep.__initialized__ === 'undefined') {
		
		HappySheep.prototype.help = function () {
			if(this.lover) {
				console.log('I\'m coming, sweet heart!');
				var self = this;
				poll();

				function poll(){
					var targetX = parseInt(self.lover.x) + 100;
					var targetY = parseInt(self.lover.y) + 10;
					console.log('I\'m here: (' + self.x + ', ' + self.y + ') now, and the target is (' + targetX + ', ' + targetY + ').');

					if(parseInt(self.x) !== targetX || 
							parseInt(self.y) !== targetY) {
						updateXY(targetX, targetY);
						setTimeout(poll, 100);
					}
				}

				function updateXY(targetX, targetY) {
					var x = parseInt(self.x);
					var y = parseInt(self.y);

					if(x - targetX < -50) {
						x += 10;
					} else if(x - targetX < 0) {
						x += 1;
					} else if ( x - targetX > 50) {
						x -= 10;
					}
					else if (x - targetX > 0) {
						x -= 1;
					}

					if(y - targetY < -50) {
						y += 10;
					}else if(y - targetY < 0) {
						y += 1;
					} else if (y - targetY > 50) {
						y -= 10;
					} else if (y - targetY > 0) {
						y -= 1;
					}

					self.x = x + 'px';
					self.y = y + 'px';
				}
			}
		};

		HappySheep.__initialized__ = true;
	}

	return this;
}; HappySheep.prototype = new UIAnimate();

var Pot = function(x, y) { UIAnimate.call(this, x, y);
}; Pot.prototype = new UIAnimate();

/**
  * View
  */
var NaiveGreenPlainView = function (model) {
	this.model = model;

	if(typeof NaiveGreenPlainView.__initialized__ === 'undefined') {
		NaiveGreenPlainView.prototype.output = function () {
			var data = 
				'<div class="green-plain" style="width: <%= width %>; height: <%= height %>; background-color: green;">' +
				'<div class="grey-wolf" style="left: <%= wolf.x %>; top: <%= wolf.y %>;" onclick="<%# wolf.laugh(\'Ha Haa Haaaaa!\'); naiveMVC.model.wolf.putToPot(naiveMVC.model.beautySheep, naiveMVC.model.pot) %>">' +
				'</div>' +
				'<div class="beauty-sheep" style="left: <%= beautySheep.x %>; top: <%= beautySheep.y %>;" onclick="<%# beautySheep.call(\'Help!!!\') %>">' +
				'</div>' + 
				'<div class="happy-sheep" style="left: <%= happySheep.x %>; top: <%= happySheep.y %>;">' +
				'</div>' +
				'<div class="pot" style="left: <%= pot.x %>; top: <%= pot.y %>;">' +
				'</div>' +
				'</div>';
			var instance = this;

			data = data.replace(/<%=\s+(.*?)\s+%>/g, function (match, group1) {
					eval('var o = instance.model.' + group1 + ';');
					return o;
					});

			data = data.replace(/<%#\s+(.*?)\s+%>/g, function (match, group1) {
					return 'naiveMVC.model.' + group1;
					});

			return data;
		};

		NaiveGreenPlainView.prototype.render = function () {
			var elem = document.getElementById('output');
			elem.innerHTML = this.output();
		};

		NaiveGreenPlainView.__initialized__ = true;
	}

	return this;
};

/**
  * Controller
  */
var GreenPlainController = function () {

	if(typeof GreenPlainController.__initialized__ === 'undefined') {
		GreenPlainController.prototype.loadView = function () {
			var greyWolf = new GreyWolf('500px', '450px');
			var happy = new HappySheep('-100px', '-100px');
			var beauty = new BeautySheep('600px', '500px', happy);
			var pot = new Pot('350px', '450px');
			
			var model = new GreenPlainModel('1000px', '700px');

			model.wolf = greyWolf;
			model.beautySheep = beauty;
			model.happySheep = happy;
			model.pot = pot;

			var view = new NaiveGreenPlainView(model);
			view.render();

			naiveMVC.model = model;

			// watch model's state and update view if needed
			function modelStatus() {
				var s = JSON.stringify({
					happySheep:{x: happy.x, y: happy.y}, 
					beautySheep: {x: beauty.x, y: beauty.y}
				});

				return s;
			}

			var current = modelStatus(); 

			function watchModel() {
				var latest = modelStatus();

				if(latest !== current) {
					current = latest;
					console.log('model changed!');

					view.render();
				}
			}	
			setInterval(watchModel, 100);
		};

		
		GreenPlainController.__initialized__ = true;
	}

	return this;
};

naiveMVC.controllers = {
	GreenPlainController: GreenPlainController
};

exports.naiveMVC = naiveMVC;
})(this);
</script>

</head>
<body controller="GreenPlainController">
<div id="output">
</div>
<script type="text/javascript">
;(function(exports, naiveMVC) {
	function bootstrapper() {
		var controllerName = document.body.getAttribute('controller');
		var controller = new naiveMVC.controllers['GreenPlainController']();
		controller.loadView();
	}

	bootstrapper();
})(this, this['naiveMVC']);
</script>
</body>
</html>

